﻿using MesGLApp.BLL;
using MesGLApp.DAL.MesDB;
using MesGLApp.DAL.MesDTO;
using MesGLApp.Tools;
using MesGLApp.View;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Gl_mes.BLL.Mes
{
    /// <summary>
    /// 用于处理工单进度的业务逻辑
    /// </summary>
    public class ProdCycleControler : BaseControler
    {
        /// <summary>
        /// 判断生产周期设定是否已经存在
        /// </summary>
        /// <param name="prodType">产品类型</param>
        /// <param name="isComp">是否齐料</param>
        /// <param name="minQty">最小适用值</param>
        /// <param name="maxQty">最大适用值</param>
        /// <returns></returns>
        public Boolean IsExistsProdCycle(string prodType, int isComp, decimal minQty, decimal maxQty)
        {
            Boolean isEx = false;
            using (MesDB ctx = new MesDB())
            {
                //先查看产品类型和是否齐料是否已经存在
                var query = ctx.ProdCycle.Where(pc => pc.ProdType == prodType && pc.IsComplete == isComp);
                if (query != null && query.Count() > 0)
                {
                    //如果已经存在，再判断范围是否会重叠
                    var qtyQuery = query.Where(pc => (pc.MinQty < minQty && minQty < pc.MaxQty) || 
                                                        (pc.MinQty < maxQty && maxQty < pc.MaxQty) || 
                                                        (minQty <= pc.MinQty && pc.MaxQty <= maxQty));
                    if (qtyQuery != null && qtyQuery.Count() > 0)
                    {
                        isEx = true;
                    }
                }
            }
            return isEx;
        }


        /// <summary>
        /// 新增生产周期设定
        /// </summary>
        /// <param name="cycle"></param>
        /// <returns></returns>
        public int InsertProdCyle(ProdCycle cycle)
        {
            int count = 0;
            using (MesDB ctx = new MesDB())
            {
                if (cycle != null)
                {
                    cycle.CreateDate = DateTime.Now;
                    cycle.CreateUser = LoginFrm.LoginUser.user_name;
                    ctx.ProdCycle.Add(cycle);
                    count = ctx.SaveChanges();
                }
            }
            return count;
        }


        /// <summary>
        /// 更新产品生产周期设定值 
        /// </summary>
        /// <param name="cycle"></param>
        /// <returns></returns>
        public int UpdateProdCycle(ProdCycle cycle,ProdCycle old_cycle)
        {
            int count = 0;
            using (MesDB ctx = new MesDB())
            {
                if (cycle != null)
                {
                    MesLog mesLog = new MesLog();
                    mesLog.TableName = "prod_cycle";
                    mesLog.TableID = cycle.ID;
                    mesLog.BeforeData = EntityTools.GetPropNameAndValue(old_cycle);
                    mesLog.AfterData = EntityTools.GetPropNameAndValue(cycle);
                    mesLog.ChangeDate = DateTime.Now;
                    mesLog.ChangeUser = LoginFrm.LoginUser.user_name;
                    mesLog.ChangeType = "update";
                    ctx.MesLogs.Add(mesLog);

                    ctx.ProdCycle.Attach(cycle);
                    ctx.Entry<ProdCycle>(cycle).State = System.Data.Entity.EntityState.Modified;

                    count = ctx.SaveChanges();
                }
            }
            return count;
        }


        /// <summary>
        /// 查询所有生产周期设定设置
        /// </summary>
        /// <returns></returns>
        public List<ProdCycle> SearchAllProdCycles()
        {
            List<ProdCycle> resList = new List<ProdCycle>();
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.ProdCycle;
                if (query != null && query.Count() > 0)
                {
                    resList = query.ToList();
                }
            }
            return resList;
        }


        /// <summary>
        /// 根据工单号查询交期设定
        /// </summary>
        /// <param name="prodNo"></param>
        /// <returns></returns>
        public SourcePPCycle SearchSourcePPCycleForProdNo(string prodNo)
        {
            SourcePPCycle resBean = new SourcePPCycle();
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.SourcePPCycle.Where(s => s.ProdNumber.Equals(prodNo));
                if (query != null && query.Count() > 0)
                {
                    resBean = query.First();
                }
            }
            return resBean;
        }


        public ProdCycle SearchProdCycleForProdSetting(string prodType, int isComp, decimal prodQty)
        {
            ProdCycle resBean = new ProdCycle();
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.ProdCycle.Where(c => c.ProdType == prodType && c.IsComplete == isComp && c.MinQty <= prodQty && prodQty < c.MaxQty);
                if (query != null && query.Count() > 0)
                {
                    resBean = query.First();
                }
            }
            return resBean;
        }

        /// <summary>
        /// 保存工单预计的生产周期
        /// </summary>
        /// <param name="prodList"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public int SaveProdProcessCycle(List<SourceProdProcessDTO> prodList)
        {
            if (prodList != null && prodList.Count > 0)
            {
                using (MesDB ctx = new MesDB())
                {
                    using (var tran = ctx.Database.BeginTransaction())
                    {
                        try 
                        {
                            int count = 0;
                            foreach (var item in prodList)
                            {
                                SourceProdProcess tmpBean = new SourceProdProcess();
                                EntityTools.CopyEntity<SourceProdProcessDTO, SourceProdProcess>(item, ref tmpBean);
                                if (item.ID == 0)
                                {
                                    tmpBean.CreateDate = this.GetCurrDateTime();
                                    tmpBean.CreateUser = LoginFrm.LoginUser.user_name;
                                    ctx.SourceProdProcesses.Add(tmpBean);
                                }
                                else if (item.ID > 0)
                                {
                                    ctx.SourceProdProcesses.Attach(tmpBean);
                                    ctx.Entry(tmpBean).State = System.Data.Entity.EntityState.Modified;
                                }

                                count = ctx.SaveChanges();

                                if (item.SourcePPCycle != null)
                                {
                                    if (item.SourcePPCycle.ID == 0)
                                    {
                                        item.SourcePPCycle.CreateDate = this.GetCurrDateTime();
                                        item.SourcePPCycle.CreateUser = LoginFrm.LoginUser.user_name;
                                        item.SourcePPCycle.SourceID = tmpBean.ID;
                                        ctx.SourcePPCycle.Add(item.SourcePPCycle);
                                    }
                                    else if (item.SourcePPCycle.ID > 0)
                                    {
                                        ctx.SourcePPCycle.Attach(item.SourcePPCycle);
                                        ctx.Entry(item.SourcePPCycle).State = System.Data.Entity.EntityState.Modified;
                                    }
                                }
                            }

                            count = ctx.SaveChanges();
                            tran.Commit();
                            return count;
                        }
                        catch (Exception ex)
                        {
                            tran.Rollback();
                            throw ex;
                        }
                    }
                }
            }
            else
            {
                throw new Exception("传入的原始工单对象为空！");
            }
        }


        /// <summary>
        /// 根据条件查询工单预设的交期
        /// </summary>
        /// <param name="prodNo">工单号</param>
        /// <param name="prodType">产品类型</param>
        /// <param name="isComp">是否齐料</param>
        /// <param name="orderDate">排单日期</param>
        /// <param name="planDate">预计交期</param>
        /// <returns></returns>
        public List<SourceProdProcessDTO> SearchProdPlanDate(string prodNo, string prodType, int? isComp = null, DateTime? orderDate = null, DateTime? planDate = null)
        {
            List<SourceProdProcessDTO> resList = new List<SourceProdProcessDTO>();
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.SourceProdProcesses
                            join b in ctx.SourcePPCycle on a.ID equals b.SourceID into res
                            from ab in res
                            select new { A = a, AB = ab };
                if (prodNo != null && prodNo.Trim().Length > 0)
                {
                    query = query.Where(res => res.A.ProdNumber.Contains(prodNo));
                }
                if (prodType != null && prodType.Trim().Length > 0 && prodType.Equals("全部") == false)
                {
                    query = query.Where(res => res.AB.ProdType.Equals(prodType));
                }
                if (isComp.HasValue)
                {
                    query = query.Where(res => (res.AB.IsComplete == (isComp ?? 0)));
                }
                if (orderDate.HasValue)
                {
                    query = query.Where(res => DbFunctions.TruncateTime(res.AB.OrderDate) == DbFunctions.TruncateTime(orderDate));
                }
                if (planDate.HasValue)
                {
                    query = query.Where(res => DbFunctions.TruncateTime(res.AB.PlanDate) == DbFunctions.TruncateTime(planDate));
                }

                if (query != null && query.Count() > 0)
                {
                    foreach (var item in query)
                    {
                        SourceProdProcessDTO tmpBean = new SourceProdProcessDTO();
                        EntityTools.CopyEntity<SourceProdProcess, SourceProdProcessDTO>(item.A,ref tmpBean);

                        tmpBean.SourcePPCycle = item.AB;

                        resList.Add(tmpBean);
                    }
                }

            }
            return resList;
        }


    }
}
